"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 硬件故障类--disk
Case Name   : 数据库重启时主节点IOwait高
Create At   : 2021/07/15
@zou_jialiang0505328126
Description :
    1.主节点注入ioWait高故障
    2.停止集群
    3.清理故障
    4.若2失败再次停止集群
    5.主节点注入故障
    6.启动集群
    7.清理故障
    8.若6失败再次启动
    9.检查集群状态
Expect      :
    1.成功
    2.主节点IOwait高时可能导致主节点上停止失败
    3.成功
    4.成功
    5.成功
    6.主节点IOwait高时可能导致主节点上启动失败
    7.成功
    8.成功
    9.成功
History     :
    Modified 2021/9/1 @wan005:适配最新CFE故障打印,并修改用例，iowait高时可能导致相应节点启停失败
"""

import unittest
from yat.test import Node, macro
from testcase.utils.Common import Common
from testcase.utils.Constant import Constant
from testcase.utils.CommonSH import CommonSH
from testcase.utils.CommonSH import RestartDbCluster
from testcase.utils.Logger import Logger


class DiskIOwait(unittest.TestCase):
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        self.log = Logger()
        self.log.info(
            '---------Opengauss_Reliability_Hardware_Case058:开始执行---------')
        self.primary_root_node = Node(node='PrimaryRoot')
        self.com = Common()
        self.constant = Constant()
        self.primary_sh = CommonSH('PrimaryDbUser')

        cmd = f"df -h {macro.DB_INSTANCE_PATH}"
        self.log.info(cmd)
        msg = self.primary_root_node.sh(cmd).result()
        self.log.info(msg)
        self.dir = msg.splitlines()[-1].split()[-1].strip()

    def test_main(self):
        text = '----step1: 主节点注入ioWait高故障 expect:成功----'
        self.log.info(text)
        inject_command = f"rIO_iowait (type,dir,bs,count,time) " \
            f"values (w_iowait,{self.dir}, 10000,10000,1000)"
        result = self.com.cfe_inject(self.primary_root_node, inject_command)
        self.log.info(result)
        result = self.com.cfe_query(self.primary_root_node, "rIO_iowait")
        self.log.info(result)
        self.assertIn(self.constant.cfe_iowait_success_msg, result,
                      '执行失败:' + text)

        text2 = '----step2 停止集群 expect:主节点IOwait高时可能导致主节点上停止失败----'
        self.log.info(text2)
        stop_result = self.primary_sh.stopDbCluster()
        self.log.info(stop_result)

        text = '----step3 清理故障 expect:成功----'
        self.log.info(text)
        for i in range(3):
            result = self.com.cfe_clean(self.primary_root_node, "rIO_iowait")
            self.log.info(result)
        result = self.com.cfe_query(self.primary_root_node, "rIO_iowait")
        self.log.info(result)
        self.assertNotIn(self.constant.cfe_iowait_success_msg, result,
                      '执行失败:' + text)

        text = '----step4 若2失败再次停止集群 expect:成功----'
        self.log.info(text)
        if not stop_result:
            result = self.primary_sh.stopDbCluster()
            self.assertTrue(result, '执行失败:' + text)

        text = '----step5: 主节点注入ioWait高故障 expect:成功----'
        self.log.info(text)
        inject_command = f"rIO_iowait (type,dir,bs,count,time) " \
            f"values (w_iowait,{self.dir}, 10000,10000,1000)"
        result = self.com.cfe_inject(self.primary_root_node, inject_command)
        self.log.info(result)
        result = self.com.cfe_query(self.primary_root_node, "rIO_iowait")
        self.log.info(result)
        self.assertIn(self.constant.cfe_iowait_success_msg, result,
                      '执行失败:' + text)

        text = '----step6 启动集群 expect:主节点IOwait高时可能导致主节点上启动失败----'
        self.log.info(text)
        start_result = self.primary_sh.startDbCluster()
        self.log.info(start_result)

        text = '----step7 清理故障 expect:成功----'
        self.log.info(text)
        for i in range(3):
            result = self.com.cfe_clean(self.primary_root_node, "rIO_iowait")
            self.log.info(result)
        result = self.com.cfe_query(self.primary_root_node, "rIO_iowait")
        self.log.info(result)
        self.assertNotIn(self.constant.cfe_iowait_success_msg, result,
                         '执行失败:' + text)

        text = '----step8 若6失败再次启动 expect:成功----'
        self.log.info(text)
        if not start_result:
            result = self.primary_sh.startDbCluster()
            self.log.info(result)
            self.assertTrue(result, '执行失败:' + text)

        text = '----step9 检查集群状态 expect:成功----'
        self.log.info(text)
        result = self.primary_sh.getDbClusterStatus("status")
        self.assertTrue(result)

    def tearDown(self):
        self.log.info("--------------主节点清理故障-------------")
        result = self.com.cfe_clean(self.primary_root_node, "rIO_iowait")
        self.log.info(result)
        result = self.com.cfe_query(self.primary_root_node, "rIO_iowait")
        self.log.info(result)
        result = self.primary_sh.getDbClusterStatus("status")
        if not result:
            self.primary_sh.stopDbCluster()
            self.primary_sh.startDbCluster()

        self.log.info(
            '--------Opengauss_Reliability_Hardware_Case058:执行完成--------')
